import { segment } from 'icqq'
import plugin from '../../lib/plugins/plugin.js'
import fetch from 'node-fetch'
import crypto from 'crypto'
import { promises as fs } from 'fs'
import fss from 'fs'
import cfg from '../../lib/config/config.js'


/**
 * 作者：千奈千祁(2632139786)
 * Gitee主页：Gitee.com/QianNQQ
 * Github主页：Github.com/QianNQQ
 * 
 * 该插件所有版本发布于 该仓库(https://gitee.com/qiannqq/yunzai-plugin-JS)
 * 本插件及该仓库的所有插件均遵循 GPL3.0 开源协议
 * 当前版本：违规图片信息管控v1.1
 * 所有更新日志(提交)请查看 该仓库(https://gitee.com/qiannqq/yunzai-plugin-JS)
 * 
 * 请勿使用本插件进行盈利等商业活动行为
 * 
 * 本插件对接的是百度云内容审核，包括鉴权方法以及接口调用
 * 
 * 该插件会对MD5值进行对比，相同图片会读取已存储的审核结果，避免额外的资源浪费
 * 
 */

//为了防止滋生额外费用，本插件采用的是白名单监听方式，只有配置的群才会监听违规图片信息
let whitelist = `123456,789456`

//配置 百度云审核应用的ApiKey和SecretKey
let bkey = {
    api_key: 'Api_Key',
    secret_key: 'Secret_Key'
}

//警告次数，当用户触发警告次数的上限时将对其进行禁言处理
let warn_not = 3

//禁言时长，单位为秒
let muted_time = 86400

export class example2 extends plugin {
  constructor () {
    super({
      name: '违规图片信息管控v1.1',
      dsc: '违规图片信息管控v1.1',
      event: 'message',
      priority: -9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999,
      rule: [
        {
            reg: '^#(图片加白|图片拉黑)$',
            fnc: 'Manual_control_of_images'
        },
        {
          reg: '',
          fnc: 'Image_Compliance_Monitor',
          log: false
        }
      ]
    })
  }
    async Manual_control_of_images(e){
        if (!e.isMaster) {
            e.reply(`你没有权限`)
            return false;
        }
        if(!e.img){
            e.reply(`加白或拉黑请一并发送图片`)
            return false
        }
        let msg = e.msg
        const msgmatch = msg.match(/#(图片加白|图片拉黑)/)
        if(msgmatch[1] == `图片加白`){
            let img_md5 = await getImageMD5(e.img);
            if (!fss.existsSync(`data/foul_imgmd5`)) {
                await fs.mkdir(`data/foul_imgmd5`)
            }
            if (fss.existsSync(`data/foul_imgmd5/${img_md5}`)) {
                let img_content = await fs.readFile(`data/foul_imgmd5/${img_md5}`, `utf-8`)
                img_content = JSON.parse(img_content)
                if(img_content.conclusion == `合规`){
                    e.reply(`该图片合规，无需加白`)
                    return false
                }
            }
            let img_md5_content = {
                conclusion: '合规',
                log_id: '10000000000000000',
                isHitMd5: 'false',
                conclusionType: '1'
            }
            imgmd5_xieru(img_md5, img_md5_content)
            e.reply(`MD5值：${img_md5}\n已加白`)
            return false
        }
        if(msgmatch[1] == `图片拉黑`){
            let img_md5 = await getImageMD5(imgUrl);
            if (!fss.existsSync(`data/foul_imgmd5`)) {
                await fs.mkdir(`data/foul_imgmd5`)
            }
            if (fss.existsSync(`data/foul_imgmd5/${img_md5}`)) {
                let img_content = await fs.readFile(`data/foul_imgmd5/${img_md5}`, `utf-8`)
                img_content = JSON.parse(img_content)
                if(img_content.conclusion == `不合规`){
                    e.reply(`该图片不合规，无需拉黑`)
                    return false
                }
            }
            let img_md5_content = {
                conclusion: '不合规',
                log_id: '10000000000000000',
                data: [
                    {
                        msg: '自定义拉黑图片不合规',
                        conclusion: '不合规'
                    }
                ],
                isHitMd5: 'false',
                conclusionType: '1'
            }
            imgmd5_xieru(img_md5, img_md5_content)
            e.reply(`MD5值：${img_md5}\n已拉黑`)
            return false
        }
    }
    async Image_Compliance_Monitor(e) {
        const whitelistArrays = whitelist.split(',');
        const iswhitelist = whitelistArrays.some(array => array.includes(e.group_id));
        if (!iswhitelist) return false
        if (!e.img) return false
        for (let imgUrl of e.img) {
            let img_md5 = await getImageMD5(imgUrl);

            if (!fss.existsSync(`data/foul_imgmd5`)) {
                await fs.mkdir(`data/foul_imgmd5`)
            }
            logger.mark(imgUrl)
            if (fss.existsSync(`data/foul_imgmd5/${img_md5}`)) {
                let img_json = await fs.readFile(`data/foul_imgmd5/${img_md5}`, `utf-8`)
                img_json = JSON.parse(img_json)
                if (img_json.conclusion == `不合规`) {
                    let msg = [segment.at(e.user_id), `\n违规图片信息：${img_json.data[0].msg}`]
                    //e.reply(msg)
                    e.recall(e.message_id)
                    await warn_user(e)
                    //e.img = `1`
                    e.msg = `1`
                    continue
                } else if (img_json.conclusion == `疑似`) {
                    e.recall(e.message_id)
                    continue
                }
                continue
            }
            //logger.mark(imgUrl)
            let res = await fetch(`https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${bkey.api_key}&client_secret=${bkey.secret_key}`)
            //logger.mark(res)
            res = await res.json()
            let acc_token = res.access_token
            let JianhuangOPENAPI = `https://aip.baidubce.com/rest/2.0/solution/v1/img_censor/v2/user_defined?access_token=${acc_token}`

            const params = new URLSearchParams();
            params.append('imgUrl', imgUrl);
            params.append('imgType', '0');
            let jieguo = await fetch(JianhuangOPENAPI, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                body: params
            })
            jieguo = await jieguo.json()
            logger.mark(jieguo)
            if (jieguo.conclusion == `不合规`) {
                let msg = [segment.at(e.user_id), `\n违规图片信息：${jieguo.data[0].msg}`]
                e.reply(msg)
                e.recall(e.message_id)
                await warn_user(e)
                let sendmastermsg = [`违规图片：${imgUrl}\n违规信息：${jieguo.data[0].msg}`]
                Bot.pickUser(cfg.masterQQ[0]).sendMsg(sendmastermsg)
                //e.img = `1`
                e.msg = `1`
                await imgmd5_xieru(img_md5, jieguo)
                continue
            } else if (jieguo.conclusion == `疑似`) {
                await imgmd5_xieru(img_md5, jieguo)
                e.recall(e.message_id)
                continue
            }

            await imgmd5_xieru(img_md5, jieguo)
            continue
        }
        return false
    }
}


async function calculateTime(mutedTime) {
    let result;
    let wenan;
    if (mutedTime > 86400) {
        wenan = `天`
        result = mutedTime / 86400;
    } else if (mutedTime > 3600) {
        wenan = `小时`
        result = mutedTime / 3600;
    } else if (mutedTime > 60) {
        wenan = `分钟`
        result = mutedTime / 60;
    } else {
        wenan = `秒`
        result = mutedTime;
    }

    return result.toFixed(2) + wenan;
}

async function warn_user(e){
    let muted_text = await calculateTime(muted_time)
    let warn_number = await redis.get(`Yunzai:foulwarn:${e.user_id}`)
    if(warn_number){
        warn_number = JSON.parse(warn_number)
        warn_not--;
        if(warn_number >= warn_not){
            warn_not++;
            await e.reply(`${e.nickname}(${e.user_id})\n你已被警告${warn_not}次及以上，超过禁言警告阈值，将对你进行禁言${muted_text}处理。如需申诉请联系群主或管理员`)
            warn_number = 0;
            e.group.muteMember(e.user_id, muted_time)
            redis.set(`Yunzai:foulwarn:${e.user_id}`, JSON.stringify(warn_number))
            return;
        } else {
            warn_number++;
            warn_not++;
            await e.reply(`${e.nickname}(${e.user_id})\n第${warn_number}次警告，发送违规图片信息。警告${warn_not}次无效将禁言${muted_text}`)
            redis.set(`Yunzai:foulwarn:${e.user_id}`, JSON.stringify(warn_number))
            return;
        }
    }
    warn_number = 1;
    e.reply(`${e.nickname}(${e.user_id})\n第${warn_number}次警告，发送违规图片信息。警告${warn_not}次无效将禁言${muted_text}`);
    redis.set(`Yunzai:foulwarn:${e.user_id}`, JSON.stringify(warn_number))
    return;
}

async function getImageMD5(url){
    const response = await fetch(url)
    const buffer = await response.arrayBuffer();
    const hash = crypto.createHash('md5')
    hash.update(Buffer.from(buffer))
    return hash.digest('hex');
}

async function imgmd5_xieru(md5, img_json){
    if(!fss.existsSync(`data/foul_imgmd5`)){
        await fs.mkdir(`data/foul_imgmd5`)
    }
    await fs.writeFile(`data/foul_imgmd5/${md5}`, JSON.stringify(img_json), `utf-8`)
}
